// CommandGen.cpp

// Implementacia CommandGen.h

#include "Common/Protocol/CommandGen.h"
#include "Common/Tasks.h"
#include "Common/Support/Debug.h"
#include <stdio.h>
//#include <string.h>


// Default verzia protokolu
#define DEFAULT_PROTOCOL "8.05"


CommandGen::CommandGen() : Module("CommandGen", "Modul - Generator prikazov", "v0.02")
{
	m_outBuff[0] = 0;
	m_pSocket	= NULL;
	m_pParser	= NULL;
	m_pSynchro	= NULL;
	memset(&m_outCounts, 0, sizeof(m_outCounts));

#ifndef COACH
	realSide = LEFT;
#endif // COACH

	Main::GetInstance()->RegisterModule(this, COMMANDS_TASK);
}


Interface* CommandGen::GetInterface(int nTask) const
{
	return (CommandsInterface*)this;
}

// Prikaz pre zmenu uhlu pohladu hraca
int CommandGen::ChangeView(ViewWidth iWidth)
{
	if(!m_pSocket)
		return 1;	// chyba
	
	m_outCounts.changeViewCount++;

	switch(iWidth)
	{
		case NARROW_VIEW:
			return m_pSocket->SendMsg("(change_view narrow high)");
		case NORMAL_VIEW:
			return m_pSocket->SendMsg("(change_view normal high)");
		case WIDE_VIEW:
			return m_pSocket->SendMsg("(change_view wide high)");
	}

	return 1;
}

// Prikaz pre inicializovanie jazyka CLang
int CommandGen::CLangInit()
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(clang (ver 8 8))");
	
	return m_pSocket->SendMsg(m_outBuff);
}

// Prikaz pre odpojenie sa od servera
int CommandGen::Disconnect()
{
	if(!m_pSocket) 
		return 1;	// chyba
	
	return m_pSocket->Disconnect("(bye)");
}

// Inicializovanie generatora prikazov
int CommandGen::Init(int argc, char** argv, int)
{
	m_pSocket = (CommunicationInterface*) Main::GetInstance()->GetInterface(COMMUNICATION_TASK);
	if (m_pSocket == NULL)
		return INIT_ERR;
	m_pParser = (MsgProcessInterface*) Main::GetInstance()->GetInterface(MESSAGE_PROCESS_TASK);
	if (m_pParser == NULL)
		return INIT_ERR;
	m_pSynchro = (SynchronizationInterface*) Main::GetInstance()->GetInterface(SYNCHRONIZATION_TASK);
	if (m_pSynchro == NULL)
		return INIT_ERR;

	return INIT_OK;
}

// Prikaz na opatovne pripojenie sa k serveru
int CommandGen::Reconnect(const char* pTeamName,unsigned uUniformNumber)
{
	if(!m_pSocket)
		return 1;	// chyba

	sprintf(m_outBuff, "(reconnect %s %d)", pTeamName, uUniformNumber);

	if(m_pParser)
		m_pParser->SetTeamName(pTeamName);

	return m_pSocket->Connect(m_outBuff);
}

// Prikaz na stav score
int CommandGen::Score()
{
	if(!m_pSocket)
		return 1;	// chyba
	
	return m_pSocket->SendMsg("(score)");
}

// Prikaz na inicializovanie komunikacie so serverom
int CommandGen::ServerInit(const char* teamName, bool goalie, const char* ver)
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(init %s (version %s)%s)", teamName, (ver == NULL) ? DEFAULT_PROTOCOL : ver, goalie ? " (goalie)" : "");
	
	if(m_pParser) 
		m_pParser->SetTeamName(teamName);

	return m_pSocket->Connect(m_outBuff);
}

// Prikaz na nastavenie skutocnej strany
void CommandGen::SetRealSide(RealSide rs)
{
#ifndef COACH
	realSide = rs;
#endif // COACH
}

// Prikaz catch
int CommandGen::Catch(float fDirection)
{
	if(!m_pSocket)
		return 1;	// chyba

	sprintf(m_outBuff, "(catch %.2f)", fDirection);
	m_outCounts.catchCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

// Prikaz dash
int CommandGen::Dash(float fPower)
{
	if(!m_pSocket)
		return 1;	// chyba

	float fPower1 = RoundFloat(fPower);
	sprintf(m_outBuff, "(dash %.2f)", fPower1);
	m_outCounts.dashCount++;

	if(!m_pSocket->SendMsg(m_outBuff))
	{
		if(m_pSynchro)
			m_pSynchro->OnExecDash(fPower1);
		return 0;
	}
	return 1;
}

// Prikaz kick
int CommandGen::Kick(float fPower, float fDirection)
{
	if(!m_pSocket)
		return 1;	// chyba

	float fPower1 = RoundFloat(fPower);
	float fDirection1 = RoundFloat(fDirection);
	
	sprintf(m_outBuff, "(kick %.2f %.2f)", fPower, fDirection);
	m_outCounts.kickCount++;

	if(!m_pSocket->SendMsg(m_outBuff))
	{
		if(m_pSynchro)
			m_pSynchro->OnExecKick(fPower1, fDirection1);
		return 0;
	}
	return 1;
}

// Prikaz move
int CommandGen::Move(float fX, float fY)
{
	if(!m_pSocket)
		return 1;	// chyba

	sprintf(m_outBuff, "(move %.2f %.2f)", fX, fY);
	m_outCounts.moveCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

// Prikaz tacle
int CommandGen::Tackle(float power)
{
	if(!m_pSocket)
		return 1;	// chyba

	sprintf(m_outBuff, "(tackle %.2f)", power);
	return m_pSocket->SendMsg(m_outBuff);
/*
	if(!m_pSocket->SendMsg(m_outBuff)) {
		if(m_pSynchro)
		m_pSynchro->OnExecKick(fPower1, fDirection1);
		return 0;
	}
	return 1;
*/
}

// Prikaz turn
int CommandGen::Turn(float fMoment)
{
	if(!m_pSocket)
		return 1;	// chyba

	float fMoment1 = RoundFloat(fMoment);
	sprintf(m_outBuff, "(turn %.2f)", fMoment1);
	m_outCounts.turnCount++;

	if(!m_pSocket->SendMsg(m_outBuff))
	{
		if(m_pSynchro)
			m_pSynchro->OnExecTurn(fMoment1);
		return 0;
	}
	return 1;
}

// Prikaz turn_neck
int CommandGen::TurnNeck(int iAngle)
{
	if(!m_pSocket)
		return 1;	// chyba

	sprintf(m_outBuff, "(turn_neck %d)", iAngle);
	m_outCounts.turnNeckCount++;

	if(!m_pSocket->SendMsg(m_outBuff))
	{
		if(m_pSynchro)
			m_pSynchro->OnExecNeck(iAngle);
		return 0;
	}
	return 1;
}

// Loptosi - mj --------------
int CommandGen::AttentionTo(int uniformNumber){
	if (!m_pSocket) {
		return 1; //chyba
	}
	sprintf(m_outBuff, "(attentionto %s %d)", m_pParser->GetTeamName(), uniformNumber);
	m_outCounts.attentiontoCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

int CommandGen::AttentionOff()
{
  if(!m_pSocket) return 1;  // error

  m_outCounts.attentiontoCount++;
  return m_pSocket->SendMsg("(attentionto off)");
}

// loptosi --------------

// Prikaz say
int CommandGen::Say(const char* pMsg)
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(say %s)", pMsg);
	m_outCounts.sayCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

// Prikaz sense_body
int CommandGen::SenseBody()
{
	if(!m_pSocket)
		return 1;	// chyba
	return m_pSocket->SendMsg("(sense_body)");
}


// V pripade koucha
#ifdef COACH

// Prikaz na zmenu typu hraca
int CommandGen::ChangePlayerType(const int uniformNumber, const int type)
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(change_player_type %d %d)", uniformNumber, type);
	m_outCounts.sayCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

//
int CommandGen::Eye(const char* onOff)
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(eye %s)", onOff);
	m_outCounts.sayCount++;

	return m_pSocket->SendMsg(m_outBuff);
}

//  
int CommandGen::TeamGraphic(int i, int j, const char* lines)
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(team_graphic (%i %i %s))", i, j, lines);

//	DBGN("send: >>%s<<", m_outBuff);
	return m_pSocket->SendMsg(m_outBuff);
}

//  
int CommandGen::TeamNames()
{
	if(!m_pSocket) 
		return 1;	// chyba

	sprintf(m_outBuff, "(team_names)");
	m_outCounts.sayCount++;

	return m_pSocket->SendMsg(m_outBuff);
}
#endif // COACH

